package com.learning.platform.service;

import com.learning.platform.dto.CourseReviewRequest;
import com.learning.platform.dto.CourseReviewResponse;

import com.learning.platform.entity.CourseReview;

import com.learning.platform.enums.ErrorCode;
import com.learning.platform.exception.BusinessException;
import com.learning.platform.repository.CourseRepository;
import com.learning.platform.repository.CourseReviewRepository;
import com.learning.platform.repository.UserRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;

@Service
@Transactional
public class CourseReviewService {
    
    private final CourseReviewRepository reviewRepository;
    private final CourseRepository courseRepository;
    private final UserRepository userRepository;
    private final EnrollmentService enrollmentService;
    
    public CourseReviewService(CourseReviewRepository reviewRepository,
                              CourseRepository courseRepository,
                              UserRepository userRepository,
                              EnrollmentService enrollmentService) {
        this.reviewRepository = reviewRepository;
        this.courseRepository = courseRepository;
        this.userRepository = userRepository;
        this.enrollmentService = enrollmentService;
    }
    
    /**
     * 提交课程评价
     */
    public CourseReviewResponse createReview(Long courseId, CourseReviewRequest request, Long userId) {
        // 检查课程是否存在
        courseRepository.findById(courseId)
                .orElseThrow(() -> new BusinessException(ErrorCode.COURSE_NOT_FOUND));
        
        // 检查用户是否已选课
        if (!enrollmentService.isEnrolled(userId, courseId)) {
            throw new BusinessException(ErrorCode.PERMISSION_DENIED, "只有选课的学员才能评价课程");
        }
        
        // 检查是否已经评价过
        if (reviewRepository.existsByUserIdAndCourseId(userId, courseId)) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "您已经评价过该课程");
        }
        
        // 创建评价
        CourseReview review = new CourseReview();
        review.setUserId(userId);
        review.setCourseId(courseId);
        review.setRating(request.getRating());
        review.setComment(request.getComment());
        
        review = reviewRepository.save(review);
        
        // 更新课程评分统计
        updateCourseRatingStats(courseId);
        
        return buildReviewResponse(review);
    }
    
    /**
     * 更新评价
     */
    public CourseReviewResponse updateReview(Long reviewId, CourseReviewRequest request, Long userId) {
        CourseReview review = reviewRepository.findById(reviewId)
                .orElseThrow(() -> new BusinessException(ErrorCode.PARAM_ERROR, "评价不存在"));
        
        // 检查权限（只能修改自己的评价）
        if (!review.getUserId().equals(userId)) {
            throw new BusinessException(ErrorCode.PERMISSION_DENIED, "只能修改自己的评价");
        }
        
        review.setRating(request.getRating());
        review.setComment(request.getComment());
        
        review = reviewRepository.save(review);
        
        // 更新课程评分统计
        updateCourseRatingStats(review.getCourseId());
        
        return buildReviewResponse(review);
    }
    
    /**
     * 删除评价
     */
    public void deleteReview(Long reviewId, Long userId) {
        CourseReview review = reviewRepository.findById(reviewId)
                .orElseThrow(() -> new BusinessException(ErrorCode.PARAM_ERROR, "评价不存在"));
        
        // 检查权限（只能删除自己的评价）
        if (!review.getUserId().equals(userId)) {
            throw new BusinessException(ErrorCode.PERMISSION_DENIED, "只能删除自己的评价");
        }
        
        Long courseId = review.getCourseId();
        reviewRepository.delete(review);
        
        // 更新课程评分统计
        updateCourseRatingStats(courseId);
    }
    
    /**
     * 获取课程评价列表
     */
    @Transactional(readOnly = true)
    public Page<CourseReviewResponse> getCourseReviews(Long courseId, Pageable pageable) {
        return reviewRepository.findByCourseIdOrderByCreatedAtDesc(courseId, pageable)
                .map(this::buildReviewResponse);
    }
    
    /**
     * 检查用户是否已评价课程
     */
    @Transactional(readOnly = true)
    public boolean hasUserReviewed(Long userId, Long courseId) {
        return reviewRepository.existsByUserIdAndCourseId(userId, courseId);
    }
    
    /**
     * 获取用户对课程的评价
     */
    @Transactional(readOnly = true)
    public CourseReviewResponse getUserReview(Long userId, Long courseId) {
        return reviewRepository.findByUserIdAndCourseId(userId, courseId)
                .map(this::buildReviewResponse)
                .orElse(null);
    }
    
    /**
     * 更新课程评分统计
     */
    private void updateCourseRatingStats(Long courseId) {
        // 计算平均评分
        BigDecimal averageRating = reviewRepository.findAverageRatingByCourseId(courseId)
                .orElse(BigDecimal.ZERO);
        
        // 计算评价总数
        long reviewCount = reviewRepository.countByCourseId(courseId);
        
        // 更新课程统计
        courseRepository.updateCourseStats(
            courseId,
            null, // 不更新选课人数
            averageRating.setScale(2, RoundingMode.HALF_UP),
            (int) reviewCount
        );
    }
    
    /**
     * 构建评价响应对象
     */
    private CourseReviewResponse buildReviewResponse(CourseReview review) {
        CourseReviewResponse response = new CourseReviewResponse();
        response.setId(review.getId());
        response.setUserId(review.getUserId());
        response.setCourseId(review.getCourseId());
        response.setRating(review.getRating());
        response.setComment(review.getComment());
        response.setCreatedAt(review.getCreatedAt());
        response.setUpdatedAt(review.getUpdatedAt());
        
        // 获取用户信息
        userRepository.findById(review.getUserId()).ifPresent(user -> {
            response.setUsername(user.getUsername());
            // 如果有头像字段的话
            // response.setUserAvatar(user.getAvatarUrl());
        });
        
        return response;
    }
}
